﻿using Ebusiness_UserService.DomainService;
using Ebusiness_UserService.DomainService.Dto;
using Ebusiness_UserService.Model;
using Ebusiness_UserService.Repositorys;
using Ebusiness_UserService.Services.Dtos.User;
using System;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;

namespace Ebusiness_UserService.Services
{
    /// <summary>
    /// 应用服务聚合间、和外部系统的业务逻辑。
    /// 
    /// 订单系统微服务、采购系统微服务、库存系统微服务。
    /// 
    /// 工作单元”(Unit of Work)
    ///    1、聚合内的若干相关联的操作组成一个"工作单元”这些工作单元要么全部成功，要么全部失败。
    ///   
    ///    2、聚合内的数据操作是关系非常紧密的，我们要保证事务的强一致性，而聚合间的协作是关系不紧密的,因此我们只要保证事务的最终一致性即可。
    ///    
    ///    3、工作单元是由应用服务层来确定，其他层不应该调用SaveChangesAsync方法保存对数据的修改。
    ///    
    ///    4、可以开发一个在控制器的方法调用结束后自动调用SaveChangesAsymc的Filter: UnitOfWorkAttribute、 UnitOfWorkFilter.
    ///    
    ///    5、应用层主要进行的是数据的校验、请求数据的获取、领域服务返回值的显示等处理，并没有复杂的业务逻辑，因为主要的业务逻辑都被封装在领域层。
    ///    
    ///    6、应用层是非常薄的一层，应用层主要进行安全认证、权限校验、数据校验、事务控制、工作单元控制、领域服务的调用等。从理论上来讲，应用层中不应该有业务规则或者业务逻辑。
    ///    
    ///    6、监听登录失败或者成功的领域事件UserAccessResultEvent，记录到LoginHistory:repository.AddNewLoginHistoryAsync(phoneNum,msg);
    /// </summary>
    [RemoteService(IsEnabled = false)]
    [Dependency(ServiceLifetime.Transient)]
    public class UserService : CrudAppService<User, UserDto, Guid>, IUserService
    {
        /// <summary>
        /// 领域服务
        /// </summary>
        public UserMannager userMannager { get; set; }

        public IUserRepository userRepository { get; set; }

        public UserService(IUserRepository repository) : base(repository)
        {
            this.userRepository = repository;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public override Task<PagedResultDto<UserDto>> GetListAsync(PagedAndSortedResultRequestDto input)
        {
            return base.GetListAsync(input);
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<User>> GetByUserList() 
        {
            var dt =  await userRepository.GetListAsync();
            return dt;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public override async Task<UserDto> CreateAsync(UserDto input)
        {
            //await userRepository.InsertAsync(new User(new PhoneNumber()));
            var user = await userRepository.FindOneAsync(input.phoneNumber);
            if (user != null)
                return new UserDto();  //伪代码 用户已经存在不添加
            var dto = ObjectMapper.Map<UserDto, User>(input);
            dto.ChangePassword(input.PasswordHash);
            dto.initializeuserAccessFail();
            var dt = await userRepository.InsertAsync(dto);
            return ObjectMapper.Map<User, UserDto>(dt);
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<string> LoginByPhoneAndPwd(LoginByPhoneAndPwdRequest req)
        {
            if (req.Password.Length < 3)
                return "密码的长度不能小于3";
            var result = await userMannager.CheckLoginAsync(req.PhoneNumber, req.Password);
            switch (result)
            {
                case UserAccessResult.OK:
                    return "登录成功";
                case UserAccessResult.PhoneNumberNotFound:
                    return "手机号或者密码错误";
                case UserAccessResult.Lockout:
                    return "用户被锁定，请稍后再试";  //避免泄密,不能404 case UserAccessResult.Lockout:
                case UserAccessResult.PasswordError:
                    return "手机号或者密码错误";
                default:
                    return "登录失败";
            }
        }
    }
}
